/**
 * Copyright 2009 Adam Ruggles.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kiff.util.parser;

import java.util.HashSet;
import java.util.Set;

/**
 * BBCode Tag Definition.
 * @author Adam
 * @version $Id$
 * 
 * Created on Jan 2, 2009 at 1:21:49 PM 
 */
public class BBCodeTagDefinition {
	/**
	 * If the tag contains a property value this is the HTML attribute name for the property.
	 */
	private final String attribute;

	/**
	 * Determines if the end tag is required (defaults to true).
	 */
	private boolean endTagRequired = true;

	/**
	 * A list of tags that are allowed to be nested inside of this tag.
	 */
	private Set<String> innerTags = new HashSet<String>();

	/**
	 * The tag name.
	 */
	private final String tagName;

	/**
	 * Constructs a tag definition with a tag name.
	 * @param tagName The tag name.
	 */
	public BBCodeTagDefinition(final String tagName) {
		this.tagName = tagName;
		this.attribute = null;
	}

	/**
	 * Constructs a tag definition with a tag name and end tag required flag.
	 * @param tagName The tag name.
	 * @param endTagRequired Whether an end tag is required for this tag.
	 */
	public BBCodeTagDefinition(final String tagName, final boolean endTagRequired) {
		this.tagName = tagName;
		this.endTagRequired = endTagRequired;
		this.attribute = null;
	}

	/**
	 * Constructs a tag definition with a tag name and attribute.
	 * @param tagName The tag name.
	 * @param endTagRequired Whether an end tag is required for this tag.
	 * @param innerTags a list of inner tags.
	 */
	public BBCodeTagDefinition(final String tagName, final boolean endTagRequired, final String... innerTags) {
		this.tagName = tagName;
		this.attribute = null;
		this.endTagRequired = endTagRequired;
		for (String innerTag : innerTags) {
			this.innerTags.add(innerTag);
		}
	}

	/**
	 * Constructs a tag definition with a tag name and attribute.
	 * @param tagName The tag name.
	 * @param attribute The HTML attribute name for the tag property.
	 */
	public BBCodeTagDefinition(final String tagName, final String attribute) {
		this.tagName = tagName;
		this.attribute = attribute;
	}

	/**
	 * Constructs a tag definition with a tag name and attribute.
	 * @param tagName The tag name.
	 * @param attribute The HTML attribute name for the tag property.
	 * @param endTagRequired Whether an end tag is required for this tag.
	 */
	public BBCodeTagDefinition(final String tagName, final String attribute, final boolean endTagRequired) {
		this.tagName = tagName;
		this.attribute = attribute;
		this.endTagRequired = endTagRequired;
	}

	/**
	 * Constructs a tag definition with a tag name and attribute.
	 * @param tagName The tag name.
	 * @param attribute The HTML attribute name for the tag property.
	 * @param endTagRequired Whether an end tag is required for this tag.
	 * @param innerTags a list of inner tags.
	 */
	public BBCodeTagDefinition(final String tagName, final String attribute, final boolean endTagRequired,
			final String... innerTags) {
		this.tagName = tagName;
		this.attribute = attribute;
		this.endTagRequired = endTagRequired;
		for (String innerTag : innerTags) {
			this.innerTags.add(innerTag);
		}
	}

	/**
	 * Adds a tag as an allowable inner tag.
	 * @param tagName The tag name.
	 */
	public void addInnerTag(final String tagName) {
		innerTags.add(tagName);
	}

	/**
	 * Returns true if the tag name is an allowable inner tag.
	 * @param tagName The name of the tag to check.
	 * @return True if the tag name is allowed, otherwise false.
	 */
	public boolean allowableInnerTag(final String tagName) {
		return innerTags.contains(tagName);
	}

	/**
	 * Returns attribute.
	 * @return the attribute.
	 */
	public String getAttribute() {
		return attribute;
	}

	/**
	 * Returns tagName.
	 * @return the tagName.
	 */
	public String getTagName() {
		return tagName;
	}

	/**
	 * Returns endTagRequired.
	 * @return the endTagRequired.
	 */
	public boolean isEndTagRequired() {
		return endTagRequired;
	}

	/**
	 * Removes a tag as an allowable inner tag.
	 * @param tagName The tag name.
	 */
	public void removeInnerTag(final String tagName) {
		innerTags.remove(tagName);
	}

	/**
	 * Sets endTagRequired.
	 * @param endTagRequired the endTagRequired to set.
	 */
	public void setEndTagRequired(final boolean endTagRequired) {
		this.endTagRequired = endTagRequired;
	}
}
